package com.demo.example;
 
/**
 * @Title: DeadLockDemo
 * @Author HeYouLong
 * @Package com.fs
 * @Date 2024/10/12 下午8:41
 * @description: 简单死锁程序演示
 */
public class DeadLockDemo {
 
    //锁a与锁b
    private static Object a = new Object();
    private static Object b = new Object();
 
    //控制拿锁的顺序，a——>b或者b——>a
    private boolean flag;
    //提供构造方法改布尔值
 
    public DeadLockDemo(boolean flag) {
        this.flag = flag;
    }
 
    public void testDeadLock() throws InterruptedException {
        if(flag){
            //a——>b
            synchronized (a){
                System.out.println(Thread.currentThread().getName()+"执行a锁代码块的资源");
                Thread.sleep(100); //模拟执行完后等待
                synchronized (b){
                    System.out.println(Thread.currentThread().getName()+"执行b锁代码块的资源");
                    Thread.sleep(100); //模拟执行完后等待
                }
            }
        }else {
            //b——>a
            synchronized (b){
                System.out.println(Thread.currentThread().getName()+"执行b锁代码块的资源");
                Thread.sleep(100); //模拟执行完后等待
                synchronized (a){
                    System.out.println(Thread.currentThread().getName()+"执行a锁代码块的资源");
                    Thread.sleep(100); //模拟执行完后等待
                }
            }
        }
    }

    public static void main(String[] args) {
        //创建不同对象
        DeadLockDemo d1 = new DeadLockDemo(true);
        DeadLockDemo d2 = new DeadLockDemo(false);

        Thread t1 = new Thread(()->{
            //线程t1的run()方法使用d1对象
            //但是在对象调用testDeadLock()使用的是共享资源的锁
            try {
                d1.testDeadLock();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        },"线程1");

        Thread t2 = new Thread(()->{
            //线程t2的run()方法使用d2对象
            // 但是在对象调用testDeadLock()使用的是共享资源的锁
            try {
                d2.testDeadLock();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        },"线程2");

        //启动线程
        t1.start();
        t2.start();
    }

}